﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.Mvc;

namespace Flagwind.Web.Filters
{
	public class InputValidationFilter : IActionFilter
	{
		#region 输入检测

		public void OnActionExecuting(ActionExecutingContext context)
		{
			if(context.ActionParameters == null || context.ActionParameters.Count < 1)
				return;

			var controller = context.Controller as Controller;

			if(controller != null && !controller.ModelState.IsValid)
			{
				var items = new List<ValidationError>();

				foreach(var state in controller.ModelState)
				{
					foreach(var error in state.Value.Errors)
					{
						items.Add(new ValidationError(state.Key, error.ErrorMessage));
					}
				}

				var action = context.ActionDescriptor as ReflectedActionDescriptor;

				if(action != null && typeof(ApiResult).IsAssignableFrom(action.MethodInfo.ReturnType))
				{
					var result = new ApiResult(ApiStatusCode.InvalidParam, items);

					context.Result = result;

					return;
				}
			}

			var dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

			foreach(var entry in context.ActionParameters)
			{
				if(entry.Value == null)
					continue;

				if(entry.Value.GetType() == typeof(string))
				{
					dictionary[entry.Key] = InputValidationUtility.Detoxify((string)entry.Value);
				}
				else if(entry.Value.GetType().IsClass)
				{
					var properties = TypeDescriptor.GetProperties(entry.Value);

					foreach(PropertyDescriptor property in properties)
					{
						if(property.PropertyType == typeof(string))
							property.SetValue(entry.Value, InputValidationUtility.Detoxify((string)property.GetValue(entry.Value)));
					}
				}
			}

			if(dictionary != null && dictionary.Count > 0)
			{
				foreach(var entry in dictionary)
				{
					context.ActionParameters[entry.Key] = entry.Value;
				}
			}
		}

		#endregion

		#region 显式实现

		void IActionFilter.OnActionExecuted(ActionExecutedContext context)
		{

		}

		#endregion
	}
}